package com.campus.customer.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.customer.bean.coupon.CouponQueryParam;
import com.campus.customer.entity.Coupon;
import com.campus.customer.entity.UserCoupon;
import com.campus.customer.mapper.CouponMapper;
import com.campus.customer.mapper.UserCouponMapper;
import com.campus.customer.vo.UserCouponVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 优惠券表 服务实现类
 * </p>
 *
 * @author ZhaoYuJie
 * @since 2025-04-02
 */
@Service
public class CouponService extends ServiceImpl<CouponMapper, Coupon> {
    @Autowired
    private CouponMapper couponMapper;
    
    @Autowired
    private UserCouponMapper userCouponMapper;

    public List<UserCouponVo> getUserCouponList(Integer userId, CouponQueryParam param) {
        return couponMapper.getUserCouponList(userId, param);
    }
    
    /**
     * 获取可领取的优惠券列表
     * 条件：发放类型为手动领取(2) && 当前时间在领取时间范围内 && 优惠券状态正常(1) && 剩余数量>0
     */
    public List<Coupon> getReceivableCoupons() {
        LocalDateTime now = LocalDateTime.now();
        LambdaQueryWrapper<Coupon> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Coupon::getIssueType, 2) // 手动领取
                .eq(Coupon::getStatus, 1) // 状态正常
                .le(Coupon::getReceiveStartTime, now) // 领取开始时间 <= 当前时间
                .ge(Coupon::getReceiveEndTime, now); // 领取结束时间 >= 当前时间
        queryWrapper.and(wrapper -> wrapper.gt(Coupon::getRemain, 0).or().eq(Coupon::getTotal, -1));// 剩余数量 > 0或者不限量

        return this.list(queryWrapper);
    }
    
    /**
     * 为新用户自动发放优惠券
     * 发放条件：issue_type=1 && issue_condition="new_user" && status=1
     */
    @Transactional
    public void grantNewUserCoupons(Integer userId) {
        // 查询符合新用户发放条件的优惠券
        LambdaQueryWrapper<Coupon> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Coupon::getIssueType, 1) // 自动发放
                .eq(Coupon::getIssueCondition, "new_user") // 新用户条件
                .eq(Coupon::getStatus, 1); // 状态正常
        
        List<Coupon> newUserCoupons = this.list(queryWrapper);
        
        LocalDateTime now = LocalDateTime.now();
        
        for (Coupon coupon : newUserCoupons) {
            try {
                // 检查优惠券是否还有剩余数量
                if (coupon.getRemain() <= 0) {
                    continue; // 跳过已发完的优惠券
                }
                
                // 检查用户是否已经领取过该优惠券（防重复发放）
                LambdaQueryWrapper<UserCoupon> userCouponQuery = new LambdaQueryWrapper<>();
                userCouponQuery.eq(UserCoupon::getUserId, userId)
                        .eq(UserCoupon::getCouponId, coupon.getId());
                long count = userCouponMapper.selectCount(userCouponQuery);
                
                if (count > 0) {
                    continue; // 已经发放过，跳过
                }
                
                // 创建用户优惠券记录
                UserCoupon userCoupon = new UserCoupon();
                userCoupon.setUserId(userId);
                userCoupon.setCouponId(coupon.getId());
                userCoupon.setUseStartTime(coupon.getUseStartTime());
                userCoupon.setUseEndTime(coupon.getUseEndTime());
                //当前时间小于使用开始时间，则设置为未生效，否则设置为可用。
                if (now.isBefore(coupon.getUseStartTime())) {
                    userCoupon.setStatus(0);
                }else {
                    userCoupon.setStatus(1);
                }
                userCoupon.setCreateTime(now);
                userCouponMapper.insert(userCoupon);
                
                // 减少优惠券剩余数量
                if (coupon.getTotal() != -1) {
                    coupon.setRemain(coupon.getRemain() - 1);
                    this.updateById(coupon);
                }
            } catch (Exception e) {
                // 记录日志但不影响其他优惠券的发放
                System.err.println("发放优惠券失败，用户ID: " + userId + ", 优惠券ID: " + coupon.getId() + ", 错误: " + e.getMessage());
            }
        }
    }
    
    /**
     * 领取优惠券
     */
    @Transactional
    public void receiveCoupon(Integer userId, Integer couponId) {
        // 1. 检查优惠券是否可领取
        Coupon coupon = this.getById(couponId);
        if (coupon == null) {
            throw new RuntimeException("优惠券不存在");
        }
        
        LocalDateTime now = LocalDateTime.now();
        if (!coupon.getIssueType().equals(2)) {
            throw new RuntimeException("该优惠券不支持手动领取");
        }
        
        if (!coupon.getStatus().equals(1)) {
            throw new RuntimeException("优惠券已失效");
        }
        
        if (now.isBefore(coupon.getReceiveStartTime()) || now.isAfter(coupon.getReceiveEndTime())) {
            throw new RuntimeException("不在领取时间范围内");
        }
        
        if (coupon.getRemain() <= 0) {
            throw new RuntimeException("优惠券已被领完");
        }
        
        // 2. 检查用户是否已领取过该优惠券（如果有限制）
        if (coupon.getReceiveLimitNum() != null && coupon.getReceiveLimitNum() > 0) {
            LambdaQueryWrapper<UserCoupon> userCouponQuery = new LambdaQueryWrapper<>();
            userCouponQuery.eq(UserCoupon::getUserId, userId)
                    .eq(UserCoupon::getCouponId, couponId);
            long count = userCouponMapper.selectCount(userCouponQuery);
            
            if (count >= coupon.getReceiveLimitNum()) {
                throw new RuntimeException("已达到领取上限");
            }
        }
        
        // 3. 创建用户优惠券记录
        UserCoupon userCoupon = new UserCoupon();
        userCoupon.setUserId(userId);
        userCoupon.setCouponId(couponId);
        userCoupon.setUseStartTime(coupon.getUseStartTime());
        userCoupon.setUseEndTime(coupon.getUseEndTime());
        //当前时间小于使用开始时间，则设置为未生效，否则设置为可用。
        if (now.isBefore(coupon.getUseStartTime())) {
            userCoupon.setStatus(0);
        }else {
            userCoupon.setStatus(1);
        }
        userCoupon.setCreateTime(now);
        userCouponMapper.insert(userCoupon);
        
        // 4. 减少优惠券剩余数量
        coupon.setRemain(coupon.getRemain() - 1);
        this.updateById(coupon);
    }
}
